/*
 * Copyright 2010 - 2011, The PLDesktop Development Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
#ifndef PLELF_IDENTIFICATION_H
#define PLELF_IDENTIFICATION_H

#include <elf/plelfheaderenums.h>
#include <stdio.h>

namespace PLSDK {

/**
 * Elf Identification block.
 */
class PLElfIdentification {
public:
	/**
	 * Identifies the file's class, or capacity.
	 */
	enum EIClass {
		/**
		 * Invalid class.
		 */
		EIClassNone		= 0,
		/**
		 * 32-bit objects.
		 */
		EIClass32		= 1,
		/**
		 * 64-bit objects.
		 */
		EIClass64		= 2
	};
	/**
	 * Specifies the encoding of both the data structures used by object file container
	 * and data contained in object file sections.
	 */
	enum EIData {
		/**
		 * Invalid data encoding.
		 */
		EIDataNone		= 0,
		/**
		 * byte address zero on the left.
		 */
		EIDataLSB		= 1,
		/**
		 * byte address zero on the right.
		 */
		EIDataMSB		= 2
	};
public:
	/**
	 * Constructor.
	 */
	inline PLElfIdentification() {}
	/**
	 * Check if the header was correct.
	 *
	 * @return True if the header was correct.
	 */
	inline bool checkHeader();
	/**
	 * Get the file class of the elf file.
	 *
	 * @return The class of the file.
	 */
	inline PLElfIdentification::EIClass fileClass();
	/**
	 * Get the data structure that was used for the data.
	 *
	 * @return The data structure.
	 */
	inline PLElfIdentification::EIData fileData();
	/**
	 * Get the version of the elf file format.
	 *
	 * @return The version.
	 */
	inline PLELFHeaderEnums::EVersion version();
	/**
	 * File identification (0x7f).
	 */
	uint8_t ei_mag0;
	/**
	 * File identification (E);
	 */
	uint8_t ei_mag1;
	/**
	 * File identification (L);
	 */
	uint8_t ei_mag2;
	/**
	 * File identification (F);
	 */
	uint8_t ei_mag3;
	/**
	 * File class.
	 */
	uint8_t ei_class;
	/**
	 * Data encoding.
	 */
	uint8_t ei_data;
	/**
	 * File version.
	 */
	uint8_t ei_version;
	/**
	 * Operating system / ABI identification.
	 */
	uint8_t ei_osapi;
	/**
	 * ABI version.
	 */
	uint8_t ei_apiversion;
	/**
	 * Start of padding bytes.
	 */
	uint8_t ei_pad;
	/**
	 * Size of e_ident[].
	 */
	uint8_t ei_nident;
} __attribute__((packed));

bool PLElfIdentification::checkHeader() {
	return (ei_mag0 == 0x7f && ei_mag1 == 0x45 /*E*/ && ei_mag2 == 0x4C /*L*/ && ei_mag3 == 0x46 /*F*/);
}

PLElfIdentification::EIClass PLElfIdentification::fileClass() {
	return (PLElfIdentification::EIClass)ei_class;
}

PLElfIdentification::EIData PLElfIdentification::fileData() {
	return (PLElfIdentification::EIData)ei_data;
}

PLELFHeaderEnums::EVersion PLElfIdentification::version() {
	return (PLELFHeaderEnums::EVersion)ei_version;
}

}

#endif
